package maosy.lib.http;

import maosy.lib.http.base.HttpDeleteWithBody;
import maosy.lib.http.base.HttpGetWithBody;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;


/**
 * Http get/post 调用工具类
 *
 * @author Mario
 */
public class HttpUtils {

    private static Logger logger = LoggerFactory.getLogger(HttpUtils.class);

    /**
     * post 请求 request body
     *
     * @param url  请求路径
     * @param data json data
     * @return String
     */
    public static String httpPostBody(String url, String data) {
        HttpPost post = new HttpPost(url);
        post.setEntity(new StringEntity(data, "UTF-8"));
        return requestBody(post);
    }

    /**
     * HTTP put 方法
     *
     * @param url  请求路径
     * @param data json data
     * @return String
     */
    public static String httpPutBody(String url, String data) {
        HttpPut put = new HttpPut(url);
        put.setEntity(new StringEntity(data, "UTF-8"));
        return requestBody(put);
    }

    public static String httpGetBody(String url, String data) {
        HttpGetWithBody get = new HttpGetWithBody(url);
        get.setEntity(new StringEntity(data, "UTF-8"));
        return requestBody(get);
    }

    /**
     * delete 请求 request body
     *
     * @param url  请求路径
     * @param data json data
     * @return String
     */
    public static String httpDeleteBody(String url, String data) {
        HttpDeleteWithBody delete = new HttpDeleteWithBody(url);
        if (StringUtils.isNotBlank(data)) delete.setEntity(new StringEntity(data, "UTF-8"));
        return requestBody(delete);
    }


    public static String httpPost(String url, List<NameValuePair> params) {
        return httpPost(url, params, null);
    }

    public static String httpPatch(String url, List<NameValuePair> pairs) {
        return httpPatch(url, pairs, null);
    }

    public static String httpGet(String url, List<NameValuePair> params) {
        return httpGet(url, params, null);
    }

    public static String httpDelete(String url, List<NameValuePair> params) {
        return httpDelete(url, params, null);
    }

    public static String httpPatch(String url, List<NameValuePair> pairs, List<Header> headers) {
        CloseableHttpClient client = HttpClients.createDefault();
        final HttpPatch patch = new HttpPatch(url);
        if (headers != null && !headers.isEmpty()) headers.forEach(patch::addHeader);
        return request(client, patch, pairs);
    }

    public static String httpPost(String url, List<NameValuePair> params, List<Header> headers) {
        CloseableHttpClient client = HttpClients.createDefault();
        final HttpPost post = new HttpPost(url);
        if (headers != null && !headers.isEmpty()) headers.forEach(post::addHeader);
        return request(client, post, params);
    }

    public static String httpDelete(String url, List<NameValuePair> params, List<Header> headers) {
        CloseableHttpClient client = HttpClients.createDefault();
        final HttpDeleteWithBody delete = new HttpDeleteWithBody(url);
        if (headers != null && !headers.isEmpty()) headers.forEach(delete::addHeader);
        return request(client, delete, params);
    }


    public static String httpGet(String url, List<NameValuePair> params, List<Header> headers) {
        if (StringUtils.isBlank(url)) return null;
        try {
            CloseableHttpClient client = HttpClients.createDefault();
            final StringBuilder urlSb = new StringBuilder(url);
            if (!url.contains("?")) urlSb.append("?");
            else urlSb.append("&");
            if (params != null) {
                urlSb.append(URLEncodedUtils.format(params, "UTF-8"));
            }
            HttpGet get = new HttpGet(urlSb.toString());
            if (headers != null && !headers.isEmpty()) headers.forEach(get::addHeader);
            HttpResponse response = client.execute(get);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                return EntityUtils.toString(response.getEntity());
            } else {
                return "请求失败:[" + response.getStatusLine().getStatusCode() + "]" + EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            logger.error(">>>>> httpGet error:" + e.getMessage(), e);
            return null;
        }
    }

    private static String request(HttpClient client, HttpEntityEnclosingRequestBase entityEnclosing, List<NameValuePair> pairs) {
        try {
            assert entityEnclosing != null;
            entityEnclosing.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
            HttpResponse response = client.execute(entityEnclosing);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                return EntityUtils.toString(response.getEntity());
            } else {
                return "请求失败:[" + response.getStatusLine().getStatusCode() + "]" + EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            logger.error(">>>>> " + entityEnclosing.getMethod() + " error:" + e.getMessage(), e);
            return null;
        }
    }


    private static String requestBody(HttpEntityEnclosingRequestBase entityEnclosing) {
        String result = null;
        try {
            entityEnclosing.setHeader("Content-Type", "application/json; charset=utf-8");
            HttpClient client = HttpClients.createDefault();
            HttpResponse response = client.execute(entityEnclosing);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK
                    || response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED
                    || response.getStatusLine().getStatusCode() == HttpStatus.SC_RESET_CONTENT) {
                result = EntityUtils.toString(response.getEntity(), "UTF-8");
            } else {
                logger.error(EntityUtils.toString(response.getEntity(), "UTF-8"));
            }
        } catch (IOException e) {
            logger.error("httpPostBody error:" + e.getMessage(), e);
        }
        return result;
    }

}
